To see the code, click on the CODE button. You can also download the whole R Markdown file from the drop down menu on the top right corner.

library(tidyverse)
library(ggtext)
library(patchwork)
library(readxl)
library(nullabor)
library(here)
library(janitor)
library(scales)
#theme_set(theme_classic())
knitr::opts_chunk$set(fig.path = "images/",
                      dev = c("png", "pdf", "svg"))
df_full <- read_xlsx(here("data/MaskedCoverage-Fig3.xlsx")) %>% 
  clean_names() %>% 
  add_row(state = c("OR", "WY", "SD", "WV", "DC", "AL")) %>% 
  mutate(row = case_when(
    state %in% c("ME") ~ 1L,
    state %in% c("VT", "NH") ~ 2L,
    state %in% c("WA", "ID", "MT", "ND", "MN", "IL", "WI", "MI", "NY", "RI", "MA") ~ 3L,
    state %in% c("OR", "NV", "WY", "SD", "IA", "IN", "OH", "PA", "NJ", "CT") ~ 4L,
    state %in% c("CA", "UT", "CO", "NE", "MO", "KY", "WV", "VA", "MD", "DE") ~ 5L,
    state %in% c("AZ", "NM", "KS", "AR", "TN", "NC", "SC", "DC") ~ 6L,
    state %in% c("OK", "LA", "MS", "AL", "GA") ~ 7L,
    state %in% c("TX", "FL") ~ 8L,
                         TRUE ~ 0L),
    col = case_when(
      state %in% c("WA", "OR", "CA") ~ 1L,
      state %in% c("ID", "NV", "UT", "AZ") ~ 2L,
      state %in% c("MT", "WY", "CO", "NM") ~ 3L,
      state %in% c("ND", "SD", "NE", "KS", "OK", "TX") ~ 4L,
      state %in% c("MN", "IA", "MO", "AR", "LA") ~ 5L,
      state %in% c("IL", "IN", "KY", "TN", "MS") ~ 6L,
      state %in% c("WI", "OH", "WV", "NC", "AL") ~ 7L,
      state %in% c("MI", "PA", "VA", "SC", "GA") ~ 8L,
      state %in% c("NY", "NJ", "MD", "DC", "FL") ~ 9L,
      state %in% c("VT", "RI", "CT", "DE") ~ 10L,
      state %in% c("ME", "NH", "MA") ~ 11L,
      TRUE ~ 0L
    ))

df_miss <- df_full %>% 
  filter(!is.na(readmission_rate))
g1 <- ggplot(df_miss, aes(col, row)) +
  geom_point(aes(size = coverage_obscured, color = readmission_rate * 100), alpha = 0.8) +
  geom_text(data = df_full, aes(label = state), color = "black", nudge_y = 0.05) +
  geom_text(aes(label = percent(readmission_rate, 0.01)), nudge_y = -0.1, size = 2.5) +
  theme_void() +
  scale_color_gradient2(low = "#3F6E9A", high = "#AB4C30", midpoint = median(df_miss$readmission_rate * 100), mid = "#E7D9C6") +
  scale_size(range = c(3, 30)) +
  scale_y_reverse() +
  theme(plot.margin = margin(r = 30)) +
  labs(color = "Readmission",
       size = "Coverage")

g2 <- ggplot(df_miss, aes(col, row)) +
  geom_point(aes(size = coverage_obscured, color = colorectal_cancer_screenings), alpha = 0.8) +
  geom_text(data = df_full, aes(label = state), color = "black", nudge_y = 0.05) +
  geom_text(aes(label = percent(colorectal_cancer_screenings/100, 0.01)), nudge_y = -0.1, size = 2.5) +
  theme_void() +
  scale_color_gradient2(low = "#3F6E9A", high = "#AB4C30", midpoint = median(df_miss$colorectal_cancer_screenings), mid = "#E7D9C6") +
  scale_size(range = c(3, 30)) +
  scale_y_reverse()  +
  labs(color = "Cancer Screening",
       size = "Coverage")

g1 + g2 + plot_layout(guides = "collect") 
This figure recreates Figure 3 in Basole et al. (2021).

Figure S1: This figure recreates Figure 3 in Basole et al. (2021).

theme_set(theme_classic())
g1 <- ggplot(df_miss, aes(coverage_obscured * 100, colorectal_cancer_screenings)) +
  geom_point() +
  labs(x = "Coverage (%)", y = "Cancer Screening (%)") +
  geom_smooth(method = loess, formula = y ~ x) +
  annotate("richtext", x = 80, y = 73, label.color = NA, fill = "transparent", label = glue::glue("R<sup>2</sup> = {scales::comma(cor(df_miss$coverage_obscured, df_miss$colorectal_cancer_screenings), 0.001)}")) 

g2 <- ggplot(df_miss, aes(coverage_obscured * 100, readmission_rate * 100)) +
  geom_point() +
  labs(x = "Coverage (%)", y = "Readmission (%)") +
  geom_smooth(method = loess, formula = y ~ x) +
  annotate("richtext", x = 80, y = 15.3, label.color = NA, fill = "transparent", label = glue::glue("R<sup>2</sup> = {scales::comma(cor(df_miss$coverage_obscured, df_miss$readmission_rate), 0.001)}")) 

g1 + g2 
This is an alternative graph design for Figure 1.

Figure S2: This is an alternative graph design for Figure 1.

set.seed(2021)
lineup_data <- null_permute("colorectal_cancer_screenings") %>% 
  lineup(true = df_miss, n = 20, pos = 3)
plot_lineup_theirs <- ggplot(lineup_data, aes(col, row)) +
  geom_point(aes(size = coverage_obscured, color = colorectal_cancer_screenings), alpha = 0.8) +
  theme_void() + 
  scale_color_gradient2(low = "#3F6E9A", high = "#AB4C30", midpoint = median(df_miss$colorectal_cancer_screenings), mid = "#E7D9C6") +
  scale_size(range = c(1, 5)) +
  scale_y_reverse(expand = c(0.1, 0.2))  +
  guides(color = "none", size = "none") + 
  facet_wrap(~.sample, ncol = 5) +
  scale_x_continuous(expand = c(0.1, 0.1)) + 
  theme(legend.position = "bottom",
        strip.text = element_text(size = 18, margin = margin(t = 3, b = 3)),
        strip.background = element_rect(color = "black", size = 1.5))

plot_lineup_theirs
The lineup for the tile grid plot.

Figure S3: The lineup for the tile grid plot.

plot_lineup_ours <- ggplot(lineup_data, aes(coverage_obscured * 100, colorectal_cancer_screenings)) +
  geom_point() +  
  geom_smooth(method = loess, formula = y ~ x) +
  facet_wrap(~.sample, ncol = 5) +
  scale_x_continuous(expand = c(0.1, 0.1)) + 
  theme(legend.position = "bottom",
        strip.text = element_text(size = 18, margin = margin(t = 3, b = 3)),
        strip.background = element_rect(color = "black", size = 1.5),
        axis.text = element_blank(),
        axis.title = element_blank(),
        axis.line = element_blank(),
        axis.ticks.length = unit(0, "pt"))

plot_lineup_ours
The lineup for the scatter plot.

Figure S4: The lineup for the scatter plot.

Same plots with higher associations between variables

The following are plots based on data that purposely modifies cancer screening to induce a higher association with the coverage.

df_false <- df_miss %>% 
  arrange(coverage_obscured) %>% 
  mutate(colorectal_cancer_screenings = sort(colorectal_cancer_screenings))

lineup_false_data <- null_permute("colorectal_cancer_screenings") %>% 
  lineup(true = df_false, n = 20, pos = 5)
plot_lineup_theirs %+% lineup_false_data
Which plot looks the most strikingly different to you?

Figure S5: Which plot looks the most strikingly different to you?

plot_lineup_ours %+% lineup_false_data
The above shows a lineup for data that was purposely manipulated so that two variables have a higher association. How easy was it to spot the data plot compared to Figure 5?

Figure S6: The above shows a lineup for data that was purposely manipulated so that two variables have a higher association. How easy was it to spot the data plot compared to Figure 5?

Acknowledgement

We thank Basole et al. (2021) for supplying us the synthetic data to draw the above plots.

Reference

Session Information
sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.0.1 (2020-06-06)
##  os       macOS  10.16                
##  system   x86_64, darwin17.0          
##  ui       X11                         
##  language (EN)                        
##  collate  en_AU.UTF-8                 
##  ctype    en_AU.UTF-8                 
##  tz       Australia/Melbourne         
##  date     2021-09-19                  
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package     * version date       lib source                           
##  assertthat    0.2.1   2019-03-21 [2] CRAN (R 4.0.0)                   
##  backports     1.2.1   2020-12-09 [1] CRAN (R 4.0.2)                   
##  bookdown      0.22.17 2021-08-07 [1] Github (rstudio/bookdown@9615b14)
##  broom         0.7.9   2021-07-27 [1] CRAN (R 4.0.2)                   
##  bslib         0.2.5   2021-05-12 [1] CRAN (R 4.0.1)                   
##  cellranger    1.1.0   2016-07-27 [2] CRAN (R 4.0.0)                   
##  class         7.3-19  2021-05-03 [2] CRAN (R 4.0.2)                   
##  cli           3.0.1   2021-07-17 [1] CRAN (R 4.0.2)                   
##  cluster       2.1.2   2021-04-17 [2] CRAN (R 4.0.2)                   
##  colorspace    2.0-1   2021-05-04 [1] CRAN (R 4.0.2)                   
##  crayon        1.4.1   2021-02-08 [1] CRAN (R 4.0.2)                   
##  DBI           1.1.1   2021-01-15 [1] CRAN (R 4.0.2)                   
##  dbplyr        2.1.1   2021-04-06 [1] CRAN (R 4.0.2)                   
##  DEoptimR      1.0-8   2016-11-19 [2] CRAN (R 4.0.0)                   
##  digest        0.6.27  2020-10-24 [1] CRAN (R 4.0.2)                   
##  diptest       0.76-0  2021-05-04 [2] CRAN (R 4.0.2)                   
##  dplyr       * 1.0.7   2021-06-18 [1] CRAN (R 4.0.2)                   
##  ellipsis      0.3.2   2021-04-29 [1] CRAN (R 4.0.2)                   
##  evaluate      0.14    2019-05-28 [2] CRAN (R 4.0.0)                   
##  fansi         0.5.0   2021-05-25 [1] CRAN (R 4.0.2)                   
##  farver        2.1.0   2021-02-28 [1] CRAN (R 4.0.2)                   
##  flexmix       2.3-17  2020-10-12 [1] CRAN (R 4.0.2)                   
##  forcats     * 0.5.1   2021-01-27 [1] CRAN (R 4.0.2)                   
##  fpc           2.2-9   2020-12-06 [2] CRAN (R 4.0.2)                   
##  fs            1.5.0   2020-07-31 [1] CRAN (R 4.0.2)                   
##  generics      0.1.0   2020-10-31 [2] CRAN (R 4.0.2)                   
##  ggplot2     * 3.3.3   2020-12-30 [1] CRAN (R 4.0.1)                   
##  ggtext      * 0.1.1   2020-12-17 [1] CRAN (R 4.0.2)                   
##  glue          1.4.2   2020-08-27 [1] CRAN (R 4.0.2)                   
##  gridtext      0.1.4   2020-12-10 [1] CRAN (R 4.0.2)                   
##  gtable        0.3.0   2019-03-25 [2] CRAN (R 4.0.0)                   
##  haven         2.4.1   2021-04-23 [2] CRAN (R 4.0.2)                   
##  here        * 1.0.1   2020-12-13 [2] CRAN (R 4.0.2)                   
##  highr         0.9     2021-04-16 [2] CRAN (R 4.0.2)                   
##  hms           1.1.0   2021-05-17 [1] CRAN (R 4.0.2)                   
##  htmltools     0.5.1.1 2021-01-22 [1] CRAN (R 4.0.2)                   
##  httr          1.4.2   2020-07-20 [1] CRAN (R 4.0.2)                   
##  janitor     * 2.1.0   2021-01-05 [2] CRAN (R 4.0.2)                   
##  jquerylib     0.1.4   2021-04-26 [1] CRAN (R 4.0.2)                   
##  jsonlite      1.7.2   2020-12-09 [1] CRAN (R 4.0.2)                   
##  kernlab       0.9-29  2019-11-12 [2] CRAN (R 4.0.0)                   
##  knitr         1.33    2021-04-24 [1] CRAN (R 4.0.2)                   
##  labeling      0.4.2   2020-10-20 [1] CRAN (R 4.0.2)                   
##  lattice       0.20-44 2021-05-02 [2] CRAN (R 4.0.2)                   
##  lifecycle     1.0.0   2021-02-15 [1] CRAN (R 4.0.2)                   
##  lubridate     1.7.10  2021-02-26 [1] CRAN (R 4.0.2)                   
##  magrittr      2.0.1   2020-11-17 [1] CRAN (R 4.0.2)                   
##  markdown      1.1     2019-08-07 [2] CRAN (R 4.0.0)                   
##  MASS          7.3-54  2021-05-03 [1] CRAN (R 4.0.2)                   
##  Matrix        1.3-3   2021-05-04 [2] CRAN (R 4.0.2)                   
##  mclust        5.4.7   2020-11-20 [2] CRAN (R 4.0.2)                   
##  mgcv          1.8-35  2021-04-18 [2] CRAN (R 4.0.2)                   
##  modelr        0.1.8   2020-05-19 [2] CRAN (R 4.0.0)                   
##  modeltools    0.2-23  2020-03-05 [2] CRAN (R 4.0.0)                   
##  moments       0.14    2015-01-05 [2] CRAN (R 4.0.0)                   
##  munsell       0.5.0   2018-06-12 [2] CRAN (R 4.0.0)                   
##  nlme          3.1-152 2021-02-04 [2] CRAN (R 4.0.2)                   
##  nnet          7.3-16  2021-05-03 [2] CRAN (R 4.0.2)                   
##  nullabor    * 0.3.9   2020-02-25 [1] CRAN (R 4.0.2)                   
##  patchwork   * 1.1.1   2020-12-17 [1] CRAN (R 4.0.2)                   
##  pillar        1.6.2   2021-07-29 [1] CRAN (R 4.0.2)                   
##  pkgconfig     2.0.3   2019-09-22 [2] CRAN (R 4.0.0)                   
##  prabclus      2.3-2   2020-01-08 [2] CRAN (R 4.0.0)                   
##  purrr       * 0.3.4   2020-04-17 [2] CRAN (R 4.0.0)                   
##  R6            2.5.1   2021-08-19 [1] CRAN (R 4.0.1)                   
##  Rcpp          1.0.7   2021-07-07 [1] CRAN (R 4.0.2)                   
##  readr       * 2.0.1   2021-08-10 [1] CRAN (R 4.0.2)                   
##  readxl      * 1.3.1   2019-03-13 [2] CRAN (R 4.0.0)                   
##  reprex        2.0.0   2021-04-02 [1] CRAN (R 4.0.2)                   
##  rlang         0.4.11  2021-04-30 [1] CRAN (R 4.0.2)                   
##  rmarkdown     2.10    2021-08-06 [1] CRAN (R 4.0.1)                   
##  robustbase    0.93-7  2021-01-04 [2] CRAN (R 4.0.2)                   
##  rprojroot     2.0.2   2020-11-15 [1] CRAN (R 4.0.2)                   
##  rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.0.1)                   
##  rvest         1.0.1   2021-07-26 [1] CRAN (R 4.0.2)                   
##  sass          0.4.0   2021-05-12 [1] CRAN (R 4.0.2)                   
##  scales      * 1.1.1   2020-05-11 [2] CRAN (R 4.0.0)                   
##  sessioninfo   1.1.1   2018-11-05 [2] CRAN (R 4.0.0)                   
##  snakecase     0.11.0  2019-05-25 [2] CRAN (R 4.0.0)                   
##  stringi       1.7.3   2021-07-16 [1] CRAN (R 4.0.2)                   
##  stringr     * 1.4.0   2019-02-10 [2] CRAN (R 4.0.0)                   
##  tibble      * 3.1.3   2021-07-23 [1] CRAN (R 4.0.2)                   
##  tidyr       * 1.1.3   2021-03-03 [1] CRAN (R 4.0.2)                   
##  tidyselect    1.1.1   2021-04-30 [1] CRAN (R 4.0.2)                   
##  tidyverse   * 1.3.1   2021-04-15 [1] CRAN (R 4.0.2)                   
##  tzdb          0.1.2   2021-07-20 [1] CRAN (R 4.0.2)                   
##  utf8          1.2.2   2021-07-24 [1] CRAN (R 4.0.2)                   
##  vctrs         0.3.8   2021-04-29 [1] CRAN (R 4.0.2)                   
##  withr         2.4.2   2021-04-18 [1] CRAN (R 4.0.2)                   
##  xfun          0.24    2021-06-15 [1] CRAN (R 4.0.2)                   
##  xml2          1.3.2   2020-04-23 [2] CRAN (R 4.0.0)                   
##  yaml          2.2.1   2020-02-01 [1] CRAN (R 4.0.2)                   
## 
## [1] /Users/etan0038/Library/R/4.0/library
## [2] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
Basole, Rahul C., Elliot Bendoly, Aravind Chandrasekaran, and Kevin Linderman. 2021. “Visualization in Operations Management Research.” INFORMS Journal on Data Science (to appear).
LS0tCnRpdGxlOiAiU3VwcGxlbWVudGFyeSBtYXRlcmlhbCBmb3IgXCJVcHJvb3Rpbmcgc3ViLXN0YW5kYXJkIHZpc3VhbGlzYXRpb24gcHJhY3RpY2VzIGZvciBkZWNpc2lvbi1tYWtpbmcgaW4gb3BlcmF0aW9uYWwgbWFuYWdlbWVudFwiIgpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliIApvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgY29kZV9mb2xkaW5nOiAiaGlkZSIKICAgIHRoZW1lOiAicGFwZXIiCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCi0tLQoKVG8gc2VlIHRoZSBjb2RlLCBjbGljayBvbiB0aGUgQ09ERSBidXR0b24uIFlvdSBjYW4gYWxzbyBkb3dubG9hZCB0aGUgd2hvbGUgUiBNYXJrZG93biBmaWxlIGZyb20gdGhlIGRyb3AgZG93biBtZW51IG9uIHRoZSB0b3AgcmlnaHQgY29ybmVyLiAKCmBgYHtyIHNldHVwLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2d0ZXh0KQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkobnVsbGFib3IpCmxpYnJhcnkoaGVyZSkKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KHNjYWxlcykKI3RoZW1lX3NldCh0aGVtZV9jbGFzc2ljKCkpCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcucGF0aCA9ICJpbWFnZXMvIiwKICAgICAgICAgICAgICAgICAgICAgIGRldiA9IGMoInBuZyIsICJwZGYiLCAic3ZnIikpCmBgYAoKCmBgYHtyIGRhdGF9CmRmX2Z1bGwgPC0gcmVhZF94bHN4KGhlcmUoImRhdGEvTWFza2VkQ292ZXJhZ2UtRmlnMy54bHN4IikpICU+JSAKICBjbGVhbl9uYW1lcygpICU+JSAKICBhZGRfcm93KHN0YXRlID0gYygiT1IiLCAiV1kiLCAiU0QiLCAiV1YiLCAiREMiLCAiQUwiKSkgJT4lIAogIG11dGF0ZShyb3cgPSBjYXNlX3doZW4oCiAgICBzdGF0ZSAlaW4lIGMoIk1FIikgfiAxTCwKICAgIHN0YXRlICVpbiUgYygiVlQiLCAiTkgiKSB+IDJMLAogICAgc3RhdGUgJWluJSBjKCJXQSIsICJJRCIsICJNVCIsICJORCIsICJNTiIsICJJTCIsICJXSSIsICJNSSIsICJOWSIsICJSSSIsICJNQSIpIH4gM0wsCiAgICBzdGF0ZSAlaW4lIGMoIk9SIiwgIk5WIiwgIldZIiwgIlNEIiwgIklBIiwgIklOIiwgIk9IIiwgIlBBIiwgIk5KIiwgIkNUIikgfiA0TCwKICAgIHN0YXRlICVpbiUgYygiQ0EiLCAiVVQiLCAiQ08iLCAiTkUiLCAiTU8iLCAiS1kiLCAiV1YiLCAiVkEiLCAiTUQiLCAiREUiKSB+IDVMLAogICAgc3RhdGUgJWluJSBjKCJBWiIsICJOTSIsICJLUyIsICJBUiIsICJUTiIsICJOQyIsICJTQyIsICJEQyIpIH4gNkwsCiAgICBzdGF0ZSAlaW4lIGMoIk9LIiwgIkxBIiwgIk1TIiwgIkFMIiwgIkdBIikgfiA3TCwKICAgIHN0YXRlICVpbiUgYygiVFgiLCAiRkwiKSB+IDhMLAogICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IDBMKSwKICAgIGNvbCA9IGNhc2Vfd2hlbigKICAgICAgc3RhdGUgJWluJSBjKCJXQSIsICJPUiIsICJDQSIpIH4gMUwsCiAgICAgIHN0YXRlICVpbiUgYygiSUQiLCAiTlYiLCAiVVQiLCAiQVoiKSB+IDJMLAogICAgICBzdGF0ZSAlaW4lIGMoIk1UIiwgIldZIiwgIkNPIiwgIk5NIikgfiAzTCwKICAgICAgc3RhdGUgJWluJSBjKCJORCIsICJTRCIsICJORSIsICJLUyIsICJPSyIsICJUWCIpIH4gNEwsCiAgICAgIHN0YXRlICVpbiUgYygiTU4iLCAiSUEiLCAiTU8iLCAiQVIiLCAiTEEiKSB+IDVMLAogICAgICBzdGF0ZSAlaW4lIGMoIklMIiwgIklOIiwgIktZIiwgIlROIiwgIk1TIikgfiA2TCwKICAgICAgc3RhdGUgJWluJSBjKCJXSSIsICJPSCIsICJXViIsICJOQyIsICJBTCIpIH4gN0wsCiAgICAgIHN0YXRlICVpbiUgYygiTUkiLCAiUEEiLCAiVkEiLCAiU0MiLCAiR0EiKSB+IDhMLAogICAgICBzdGF0ZSAlaW4lIGMoIk5ZIiwgIk5KIiwgIk1EIiwgIkRDIiwgIkZMIikgfiA5TCwKICAgICAgc3RhdGUgJWluJSBjKCJWVCIsICJSSSIsICJDVCIsICJERSIpIH4gMTBMLAogICAgICBzdGF0ZSAlaW4lIGMoIk1FIiwgIk5IIiwgIk1BIikgfiAxMUwsCiAgICAgIFRSVUUgfiAwTAogICAgKSkKCmRmX21pc3MgPC0gZGZfZnVsbCAlPiUgCiAgZmlsdGVyKCFpcy5uYShyZWFkbWlzc2lvbl9yYXRlKSkKYGBgCgoocmVmOm1pbWljYXJ5KSBUaGlzIGZpZ3VyZSByZWNyZWF0ZXMgRmlndXJlIDMgaW4gQGJhc29sZTIwMjEuCgpgYGB7ciBtaW1pYy1vcmlnaW5hbCwgZmlnLmhlaWdodCA9IDgsIGZpZy53aWR0aCA9IDE4LCBmaWcuY2FwID0gIihyZWY6bWltaWNhcnkpIn0KZzEgPC0gZ2dwbG90KGRmX21pc3MsIGFlcyhjb2wsIHJvdykpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gY292ZXJhZ2Vfb2JzY3VyZWQsIGNvbG9yID0gcmVhZG1pc3Npb25fcmF0ZSAqIDEwMCksIGFscGhhID0gMC44KSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBkZl9mdWxsLCBhZXMobGFiZWwgPSBzdGF0ZSksIGNvbG9yID0gImJsYWNrIiwgbnVkZ2VfeSA9IDAuMDUpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChyZWFkbWlzc2lvbl9yYXRlLCAwLjAxKSksIG51ZGdlX3kgPSAtMC4xLCBzaXplID0gMi41KSArCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gIiMzRjZFOUEiLCBoaWdoID0gIiNBQjRDMzAiLCBtaWRwb2ludCA9IG1lZGlhbihkZl9taXNzJHJlYWRtaXNzaW9uX3JhdGUgKiAxMDApLCBtaWQgPSAiI0U3RDlDNiIpICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygzLCAzMCkpICsKICBzY2FsZV95X3JldmVyc2UoKSArCiAgdGhlbWUocGxvdC5tYXJnaW4gPSBtYXJnaW4ociA9IDMwKSkgKwogIGxhYnMoY29sb3IgPSAiUmVhZG1pc3Npb24iLAogICAgICAgc2l6ZSA9ICJDb3ZlcmFnZSIpCgpnMiA8LSBnZ3Bsb3QoZGZfbWlzcywgYWVzKGNvbCwgcm93KSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBjb3ZlcmFnZV9vYnNjdXJlZCwgY29sb3IgPSBjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzKSwgYWxwaGEgPSAwLjgpICsKICBnZW9tX3RleHQoZGF0YSA9IGRmX2Z1bGwsIGFlcyhsYWJlbCA9IHN0YXRlKSwgY29sb3IgPSAiYmxhY2siLCBudWRnZV95ID0gMC4wNSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MvMTAwLCAwLjAxKSksIG51ZGdlX3kgPSAtMC4xLCBzaXplID0gMi41KSArCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gIiMzRjZFOUEiLCBoaWdoID0gIiNBQjRDMzAiLCBtaWRwb2ludCA9IG1lZGlhbihkZl9taXNzJGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MpLCBtaWQgPSAiI0U3RDlDNiIpICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygzLCAzMCkpICsKICBzY2FsZV95X3JldmVyc2UoKSAgKwogIGxhYnMoY29sb3IgPSAiQ2FuY2VyIFNjcmVlbmluZyIsCiAgICAgICBzaXplID0gIkNvdmVyYWdlIikKCmcxICsgZzIgKyBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIpIApgYGAKCihyZWY6ZmlnMy1hbHQpIFRoaXMgaXMgYW4gYWx0ZXJuYXRpdmUgZ3JhcGggZGVzaWduIGZvciBGaWd1cmUgXEByZWYoZmlnOm1pbWljLW9yaWdpbmFsKS4KCmBgYHtyIGZpZzMtYWx0LCBmaWcuaGVpZ2h0ID0gNCwgZmlnLndpZHRoID0gOCwgZmlnLmNhcCA9ICIocmVmOmZpZzMtYWx0KSJ9CnRoZW1lX3NldCh0aGVtZV9jbGFzc2ljKCkpCmcxIDwtIGdncGxvdChkZl9taXNzLCBhZXMoY292ZXJhZ2Vfb2JzY3VyZWQgKiAxMDAsIGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MpKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHggPSAiQ292ZXJhZ2UgKCUpIiwgeSA9ICJDYW5jZXIgU2NyZWVuaW5nICglKSIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSBsb2VzcywgZm9ybXVsYSA9IHkgfiB4KSArCiAgYW5ub3RhdGUoInJpY2h0ZXh0IiwgeCA9IDgwLCB5ID0gNzMsIGxhYmVsLmNvbG9yID0gTkEsIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBsYWJlbCA9IGdsdWU6OmdsdWUoIlI8c3VwPjI8L3N1cD4gPSB7c2NhbGVzOjpjb21tYShjb3IoZGZfbWlzcyRjb3ZlcmFnZV9vYnNjdXJlZCwgZGZfbWlzcyRjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzKSwgMC4wMDEpfSIpKSAKCmcyIDwtIGdncGxvdChkZl9taXNzLCBhZXMoY292ZXJhZ2Vfb2JzY3VyZWQgKiAxMDAsIHJlYWRtaXNzaW9uX3JhdGUgKiAxMDApKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHggPSAiQ292ZXJhZ2UgKCUpIiwgeSA9ICJSZWFkbWlzc2lvbiAoJSkiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gbG9lc3MsIGZvcm11bGEgPSB5IH4geCkgKwogIGFubm90YXRlKCJyaWNodGV4dCIsIHggPSA4MCwgeSA9IDE1LjMsIGxhYmVsLmNvbG9yID0gTkEsIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBsYWJlbCA9IGdsdWU6OmdsdWUoIlI8c3VwPjI8L3N1cD4gPSB7c2NhbGVzOjpjb21tYShjb3IoZGZfbWlzcyRjb3ZlcmFnZV9vYnNjdXJlZCwgZGZfbWlzcyRyZWFkbWlzc2lvbl9yYXRlKSwgMC4wMDEpfSIpKSAKCmcxICsgZzIgCmBgYAoKYGBge3IgbGluZXVwLWRhdGF9CnNldC5zZWVkKDIwMjEpCmxpbmV1cF9kYXRhIDwtIG51bGxfcGVybXV0ZSgiY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncyIpICU+JSAKICBsaW5ldXAodHJ1ZSA9IGRmX21pc3MsIG4gPSAyMCwgcG9zID0gMykKYGBgCgoocmVmOmxpbmV1cC10aGVpcnMpIFRoZSBsaW5ldXAgZm9yIHRoZSB0aWxlIGdyaWQgcGxvdC4KCmBgYHtyIGxpbmV1cC10aGVpcnMsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTAsIGZpZy5jYXAgPSAiKHJlZjpsaW5ldXAtdGhlaXJzKSJ9CnBsb3RfbGluZXVwX3RoZWlycyA8LSBnZ3Bsb3QobGluZXVwX2RhdGEsIGFlcyhjb2wsIHJvdykpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gY292ZXJhZ2Vfb2JzY3VyZWQsIGNvbG9yID0gY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncyksIGFscGhhID0gMC44KSArCiAgdGhlbWVfdm9pZCgpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICIjM0Y2RTlBIiwgaGlnaCA9ICIjQUI0QzMwIiwgbWlkcG9pbnQgPSBtZWRpYW4oZGZfbWlzcyRjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzKSwgbWlkID0gIiNFN0Q5QzYiKSArCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMSwgNSkpICsKICBzY2FsZV95X3JldmVyc2UoZXhwYW5kID0gYygwLjEsIDAuMikpICArCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiLCBzaXplID0gIm5vbmUiKSArIAogIGZhY2V0X3dyYXAofi5zYW1wbGUsIG5jb2wgPSA1KSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMC4xLCAwLjEpKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBtYXJnaW4gPSBtYXJnaW4odCA9IDMsIGIgPSAzKSksCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxLjUpKQoKcGxvdF9saW5ldXBfdGhlaXJzCmBgYAoKKHJlZjpsaW5ldXAtb3VycykgVGhlIGxpbmV1cCBmb3IgdGhlIHNjYXR0ZXIgcGxvdC4KCmBgYHtyIGxpbmV1cC1vdXJzLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwLCBmaWcuY2FwID0gIihyZWY6bGluZXVwLW91cnMpIn0KcGxvdF9saW5ldXBfb3VycyA8LSBnZ3Bsb3QobGluZXVwX2RhdGEsIGFlcyhjb3ZlcmFnZV9vYnNjdXJlZCAqIDEwMCwgY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncykpICsKICBnZW9tX3BvaW50KCkgKyAgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gbG9lc3MsIGZvcm11bGEgPSB5IH4geCkgKwogIGZhY2V0X3dyYXAofi5zYW1wbGUsIG5jb2wgPSA1KSArCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZCA9IGMoMC4xLCAwLjEpKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBtYXJnaW4gPSBtYXJnaW4odCA9IDMsIGIgPSAzKSksCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxLjUpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLmxlbmd0aCA9IHVuaXQoMCwgInB0IikpCgpwbG90X2xpbmV1cF9vdXJzCmBgYAoKCgojIFNhbWUgcGxvdHMgd2l0aCBoaWdoZXIgYXNzb2NpYXRpb25zIGJldHdlZW4gdmFyaWFibGVzCgpUaGUgZm9sbG93aW5nIGFyZSBwbG90cyBiYXNlZCBvbiBkYXRhIHRoYXQgcHVycG9zZWx5IG1vZGlmaWVzIGNhbmNlciBzY3JlZW5pbmcgdG8gaW5kdWNlIGEgaGlnaGVyIGFzc29jaWF0aW9uIHdpdGggdGhlIGNvdmVyYWdlLiAKCmBgYHtyIGRhdGEtZmFsc2V9CmRmX2ZhbHNlIDwtIGRmX21pc3MgJT4lIAogIGFycmFuZ2UoY292ZXJhZ2Vfb2JzY3VyZWQpICU+JSAKICBtdXRhdGUoY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncyA9IHNvcnQoY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncykpCgpsaW5ldXBfZmFsc2VfZGF0YSA8LSBudWxsX3Blcm11dGUoImNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MiKSAlPiUgCiAgbGluZXVwKHRydWUgPSBkZl9mYWxzZSwgbiA9IDIwLCBwb3MgPSA1KQpgYGAKCihyZWY6bGluZXVwLXRoZWlycy1mYWxzZSkgV2hpY2ggcGxvdCBsb29rcyB0aGUgbW9zdCBzdHJpa2luZ2x5IGRpZmZlcmVudCB0byB5b3U/CgpgYGB7ciBsaW5ldXAtdGhlaXJzLWZhbHNlLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwLCBmaWcuY2FwID0gIihyZWY6bGluZXVwLXRoZWlycy1mYWxzZSkifQpwbG90X2xpbmV1cF90aGVpcnMgJSslIGxpbmV1cF9mYWxzZV9kYXRhCmBgYAoKKHJlZjpsaW5ldXAtb3Vycy1mYWxzZSkgVGhlIGFib3ZlIHNob3dzIGEgbGluZXVwIGZvciBkYXRhIHRoYXQgd2FzIHB1cnBvc2VseSBtYW5pcHVsYXRlZCBzbyB0aGF0IHR3byB2YXJpYWJsZXMgaGF2ZSBhIGhpZ2hlciBhc3NvY2lhdGlvbi4gSG93IGVhc3kgd2FzIGl0IHRvIHNwb3QgdGhlIGRhdGEgcGxvdCBjb21wYXJlZCB0byBGaWd1cmUgXEByZWYoZmlnOmxpbmV1cC10aGVpcnMtZmFsc2UpPwoKYGBge3IgbGluZXVwLW91cnMtZmFsc2UsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTAsIGZpZy5jYXAgPSAiKHJlZjpsaW5ldXAtb3Vycy1mYWxzZSkifQpwbG90X2xpbmV1cF9vdXJzICUrJSBsaW5ldXBfZmFsc2VfZGF0YQpgYGAKCgojIEFja25vd2xlZGdlbWVudCAKCldlIHRoYW5rIEBiYXNvbGUyMDIxIGZvciBzdXBwbHlpbmcgdXMgdGhlIHN5bnRoZXRpYyBkYXRhIHRvIGRyYXcgdGhlIGFib3ZlIHBsb3RzLiAKCiMgUmVmZXJlbmNlCgo8ZGV0YWlscz4KPHN1bW1hcnk+U2Vzc2lvbiBJbmZvcm1hdGlvbjwvc3VtbWFyeT4KYGBge3Igc2Vzc2lvbi1pbmZvfQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkKYGBgCjwvZGV0YWlscz4K